package com.cy.sportassistant.tools;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import dev.langchain4j.internal.ValidationUtils;
import dev.langchain4j.web.search.*;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BochaWebSearchEngine implements WebSearchEngine {
    private final String baseUrl;
    private final String apiKey;
    private final Duration timeout;
    private final String freshness;
    private final Boolean includeSummary;
    private final HttpClient httpClient;

    private BochaWebSearchEngine(Builder builder) {
        this.baseUrl = builder.baseUrl;
        this.apiKey = ValidationUtils.ensureNotNull(builder.apiKey, "apiKey");
        this.timeout = builder.timeout;
        this.freshness = builder.freshness;
        this.includeSummary = builder.includeSummary;
        this.httpClient = HttpClient.newBuilder()
                .connectTimeout(this.timeout)
                .build();
    }

    public static Builder builder() {
        return new Builder();
    }

    @Override
    public WebSearchResults search(WebSearchRequest webSearchRequest) {
        try {
            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("query", webSearchRequest.searchTerms());
            requestBody.put("freshness", freshness);
            requestBody.put("summary", includeSummary);
            requestBody.put("count", webSearchRequest.maxResults());

            // 发送请求
            HttpRequest httpRequest = HttpRequest.newBuilder()
                    .uri(URI.create(baseUrl + "web-search"))
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + apiKey)
                    .POST(HttpRequest.BodyPublishers.ofString(requestBody.toJSONString()))
                    .build();

            HttpResponse<String> response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());

            if (response.statusCode() != 200) {
                throw new RuntimeException("HTTP request failed with status: " + response.statusCode());
            }

            // 解析响应
            JSONObject jsonResponse = JSON.parseObject(response.body());
            int code = jsonResponse.getIntValue("code");
            if (code != 200) {
                throw new RuntimeException("Search failed with code: " + code + ", message: " + jsonResponse.getString("msg"));
            }

            // 提取搜索结果
            List<WebSearchOrganicResult> results = new ArrayList<>();
            JSONObject data = jsonResponse.getJSONObject("data");
            if (data != null) {
                JSONObject webPages = data.getJSONObject("webPages");
                if (webPages != null) {
                    List<JSONObject> pages = webPages.getJSONArray("value").toJavaList(JSONObject.class);
                    for (JSONObject page : pages) {
                        results.add(WebSearchOrganicResult.from(
                                page.getString("name"),
                                URI.create(page.getString("url")),
                                page.getString("snippet"),
                                page.getString("summary")
                        ));

                    }
                }
            }

            // 构建搜索信息
            long totalResults = 0;
            if (data != null && data.getJSONObject("webPages") != null) {
                totalResults = data.getJSONObject("webPages").getLongValue("totalEstimatedMatches");
            }
            WebSearchInformationResult searchInformation = WebSearchInformationResult.from(totalResults);

            // 构建元数据
            Map<String, Object> metadata = new HashMap<>();
            metadata.put("logId", jsonResponse.getString("log_id"));
            if (data != null && data.getJSONObject("queryContext") != null) {
                metadata.put("originalQuery", data.getJSONObject("queryContext").getString("originalQuery"));
            } else {
                metadata.put("originalQuery", webSearchRequest.searchTerms());
            }

            return WebSearchResults.from(metadata, searchInformation, results);
        } catch (Exception e) {
            throw new RuntimeException("Failed to perform search", e);
        }
    }

    public static class Builder {
        private String baseUrl = "https://api.bochaai.com/v1/";
        private String apiKey;
        private Duration timeout = Duration.ofSeconds(60);
        private String freshness = "noLimit";
        private Boolean includeSummary = false;

        public Builder baseUrl(String baseUrl) {
            this.baseUrl = baseUrl;
            return this;
        }

        public Builder apiKey(String apiKey) {
            this.apiKey = apiKey;
            return this;
        }

        public Builder timeout(Duration timeout) {
            this.timeout = timeout;
            return this;
        }

        public Builder freshness(String freshness) {
            this.freshness = freshness;
            return this;
        }

        public Builder includeSummary(Boolean includeSummary) {
            this.includeSummary = includeSummary;
            return this;
        }

        public BochaWebSearchEngine build() {
            return new BochaWebSearchEngine(this);
        }
    }
}